<?php

/**
 * Library :: Image :: Transform :: GD
 *
 * This is the GD Interface class for handling image
 * transformations.
 * 
 * Warlock is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 *
 * @package    warlock
 * @author     David Cole <neophyte@sourcetutor.com>
 * @license    GNU/GPL v2
 */

using('Library.Image.Transform.Common');
using('Library.FileSystem');

class Image_Transform_GD extends Image_Transform_Common 
{
    /**
     * GD Image Resource
     *
     * @var resource
     * @access private
     */
    var $_Resource;
    
    /**
     * True Color Image ?
     *
     * @var bool
     * @access private
     */
    var $_TrueColor;
        
    /**
     * Class Constructor
     * 
     * Determines the type of the image to be loaded and
     * grabs a GD Resource of the image.
     *
     * @param string $image  Location of image to be opened
     */
    function __construct($image)
    {
        parent::__construct();
        
        switch (filemime($image))
        {
            case 'image/gif'  : $this->Type = 'gif';  break;
            case 'image/jpeg' : $this->Type = 'jpeg'; break;
            case 'image/png'  : $this->Type = 'png';  break;
        }
        
        $func             = 'imagecreatefrom'.$this->Type;
        $this->_Resource  = $func($image);
        $this->_TrueColor = imageistruecolor($this->_Resource);
    }
    
    /**
     * Draw Text
     *
     * Writes text on the open image based on the given params.
     * 
     * @param string  $text   Text to be written
     * @param int     $x      X start position of text
     * @param int     $y      Y start position of text
     * @param mixed   $color  Color of the text
     * @param string  $font   Font to be used
     * @param int     $size   Size of the text
     * @param int     $angle  Angle of the text
     * 
     * @return bool
     * @access public
     */
    function DrawText($text, $x = 0, $y = 0, $color = '#000000', $font = 'verdana', $size = 10, $angle = 0) 
    {
        $color = $this->_GetColor($color);
        $color = imagecolorresolve($color[0], $color[1], $color[2]);
        
        imagettftext($this->_Resource, $size, $angle, $x, $y, $color, $font, $text);
        
        return true;
    }
    
    /**
     * Overlay Image
     *
     * Overlays an existing image on top of the currently open image.
     * 
     * @param string  $image    Location of the image to be overlayed
     * @param int     $x        Destination X Point start
     * @param int     $y        Destination Y Point start
     * @param int     $opacity  Opacity to set the source image to
     * @param int     $src_x    Source X Point start
     * @param int     $src_y    Source Y point start
     * @param int     $width    Source Width (uses entire width by default)
     * @param int     $height   Source Height (uses entire height by default)
     * 
     * @return bool
     * @access public
     */
    function OverlayImage($image, $x = 0, $y = 0, $opacity = 1.0, $src_x = 0, $src_y = 0, $width = 0, $height = 0)
    {
        
    }
    
    /**
     * Draw Border
     * 
     * Draws a border around the outside of the image (increases the dimensions
     * of the image in the process)
     *
     * @param int    $width  Width of the border
     * @param mixed  $color  Border color
     * 
     * @return bool
     * @access public
     */
    function DrawBorder($width = 1, $color = '#000000')
    {
        $this->Width  += 2 * $width;
        $this->Height += 2 * $width;
        
        $res   = $this->_CreateImage($this->Width, $this->Height);
        $color = $this->_GetColor($color);
        
        if ($this->true_color)
        {
            $c = imagecolorresolve($this->_Resource, $color[0], $color[1], $color[2]);
            imagefill($res, 0, 0, $c);
        }
        else
            imagecolorset($res, imagecolorat($res, 0, 0), $color[0], $color[1], $color[2]);
                    
        imagecopy($res, $this->_Resource, $width, $width, 0, 0, $this->Width, $this->Height);
        $this->_Resource = $res;        
    }
    
    /**
     * Adjust Image Gamma
     *
     * @param float $gamma  How much gamma should be adjusted
     * 
     * @return bool
     * @access publix
     */
    function Gamma($gamma = 1.0)
    {
        if ($gamma != 1.0)
            imagegammacorrect($this->_Resource, 1.0, floatval($gamma));
        
        return true;
    }
    
    /**
     * Make the Image Grayscale
     * 
     * @return bool
     * @access public
     *
     */
    function Grayscale()
    {
        imagecopymergegray($this->_Resource, $this->_Resource, 0, 0, 0, 0, $this->Width, $this->Height, 0);
    }
    
    /**
     * Resize Image
     *
     * @param int    $width   New image width
     * @param int    $height  New image height
     * @param string $method  Scale method pixel|smooth
     * 
     * @return bool
     * @access public
     */
    function Resize($width, $height, $method = 'pixel')
    {
        
    }
    
    /**
     * Crop the Image
     *
     * @param int $width   Width of cropped image
     * @param int $height  Height of cropped image
     * @param int $x       X Point to crop from
     * @param int $y       Y Point to crop from
     * 
     * @return bool
     * @access public
     */
    Function Crop($width, $height, $x = 0, $y = 0)
    {      
        $width   = min($width,  $this->Width - $x - 1);
        $height  = min($height, $this->Height - $y - 1);
        $res     = $this->_CreateImage($width, $height);

        imagecopy($res, $this->_Resource, 0, 0, $x, $y, $width, $height);
        
        $this->_Resource = $res;
        $this->Width     = $width;
        $this->Height    = $height;
        
        return true;                          
    }
    
    
    /**
     * Flip (Vertically Mirror Image)
     *
     * @return bool
     * @access public
     */
    function Flip()
    {
        $res = $this->_CreateImage();
        
        for ($y = 0; $y < $this->Height; $y++)
            imagecopy($res, $this->_Resource, 0, $y, 0, $this->Height - $y - 1, $this->Width, 1);
            
        imagedestroy($this->_Resource);
        $this->_Resource = $res;
        
        return true;
    }
    
    /**
     * Mirror (Horizontally Mirror Image)
     *
     * @return bool
     * @access public
     */
    function Mirror()
    {
        $res = $this->_CreateImage();
        
        for ($x = 0; $x < $this->Width; $x++)
            imagecopy($res, $this->_Resource, $x, 0, $this->Width - $x - 1, 0, 1, $this->Height);
        
        imagedestroy($this->_Resource);
        $this->_Resource = $res;
        
        return true;        
    }
    
    /**
     * Rotate Image
     *
     * @param int    $angle         Number of degrees the image should be rotated by
     * @param mixed  $canvas_color  Color to use as the image background
     * 
     * @return unknown
     * @access public
     */
    function Rotate($angle, $canvas_color = '#000000')
    {
        if (($angle % 360) == 0)
            return true;
            
        $color           = $this->_GetColor($canvas_color);
        $color           = imagecolorresolve($this->_Resource, $color[0], $color[1], $color[2]);
        $this->_Resource = imagerotate($this->_Resource, $angle * -1, $color);
        
        return true;
    }
    
    /**
     * Save the Image to file
     *
     * @param string  $filename  Location the image should be saved to
     * @param string  $type      The output type to be used to save the file
     * @param int     $quality   Applies to jpegs only 1-100
     * 
     * @return unknown
     * @access public
     */
    function Save($filename, $type = '', $quality = null)
    {
        $type = strtolower(($type == '') ? $this->Type : $type);        
        $func = 'image'.$type;
        
        switch ($type)
        {
            case 'jpeg':
                $result = $func($this->_Resource, $filename, $quality);
                break;
            default:
                $result = $func($this->_Resource, $filename);
        }

        return true;        
    }
    
    /**
     * Create Image
     *
     * Create a new temporary GD image resource.
     * 
     * @param int   $width     
     * @param int   $height
     * @param bool  $truecolor  Should the image be truecolor ?
     * 
     * @return unknown
     * @access public
     */
    function _CreateImage($width = -1, $height = -1, $truecolor = null)
    {
        if ($width == -1)
            $width = $this->Width;
        
        if ($height == -1)
            $height = $this->Height;
        
        $res = null;
        
        if (is_null($truecolor))
        {
            if (function_exists('imageistruecolor'))
                $createtruecolor = imageistruecolor($this->_Resource);
            else
                $createtruecolor = true;            
        }
        else
            $createtruecolor = $truecolor;
        
        if ($createtruecolor && function_exists('imagecreatetruecolor'))
            $res = @imagecreatetruecolor($width, $height);
        
        if (!$res)
        {
            $res = imagecreate($width, $height);
            imagepalettecopy($res, $this->_Resource);
            $color = imagecolortransparent($this->_Resource);
            
            if ($color != -1)
            {
                imagecolortransparent($res, $color);
                imagefill($res, 0, 0, $color);
            }
        }
        return $res;
    }    
}

?>